﻿#define _CRT_SECURE_NO_WARNINGS 1

//// 六种类的成员函数
//class Date
//{
//	// 空类：大小默认为1
//};

// 1.构造函数——Init功能——在对象进行实例化时用来初始化对象的
//#include <iostream>
//using namespace std;

//class Date
//{
//public:
//	Date(int year = 1998, int month = 1, int day = 1)// 构造函数：函数名和类名相同，没有返回值
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "年" << _month << "月" << _day << "日" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//Stack func2()
//{
//	Stack st;
//	return st;// 传值返回不会返回st，而是返回st的拷贝，先返回给临时对象，临时对象再返回回去
//}
//
//Stack& func2()
//{
//	Stack st;
//	return st;
//}
//
//int main()
//{
//	Stack ret = func2();
//
//	return 0;
//}
//
//int main()
//{
//	Stack ret = func2();
//	return 0;
//}
//

//
//// 日期类的实现
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//	// 没有显示写构造函数，编译器会自动生成
//	void Print()
//	{
//		cout << _year << "年" << _month << "月" << _day << "日" << endl;
//	}
//
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	Date d1;
//	d1.Print();
//
//	return 0;
//}
//// -858993460年-858993460月-858993460日   生成的是随机值
//

//// 大多数情况下构造函数都需要我们自己去实现，
//// 少数像MyQueue且Stack有默认构造函数时MyQueue自动生成的构造函数就可以使用。
//#include <iostream>
//using namespace std;
//typedef int STDataType;
//class Stack
//{
//public:
//	// 构造函数
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//
//class MyQueue
//{
//public:
//	// 没有实现MyQueue的构造函数
//
//private:
//	Stack pushst;
//	Stack popst;// 自定义成员变量要调用构造函数（Stack的构造函数）进行初始化
//};
//
//int main()
//{
//	// Stack st;
//	MyQueue mq;// 调用了两次Stack的构造函数，所以不用写MyQueue的构造函数
//
//	return 0;
//}

//// 构造函数的种类
//#include <iostream>
//using namespace std;
//
//class Date
//{
//public:
//	// 无参构造函数
//	Date()
//	{
//		_year = 2000;
//		_month = 1;
//		_day = 1;
//	}
//
//	// 带参构造函数
//	Date(int year, int month, int day)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//
//	//// 全缺省构造函数
//	//Date(int year = 1998, int month = 1, int day = 1)// 构造函数：函数名和类名相同，没有返回值
//	//{
//	//	_year = year;
//	//	_month = month;
//	//	_day = day;
//	//}
//	void Print()
//	{
//		cout << _year << "年" << _month << "月" << _day << "日" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	// 注释掉1、3个构造函数：error C2512: “Date”: 没有合适的默认构造函数可用
//	Date d1;// 这里调用无参构造函数，但是没有无参的构造函数，
//			// 因为用户已经自己定义了一个，编译器不会再自己生成了
//
//	Date d2(2024, 11, 22);
//
//	// Date d3(); // 注意：不能加括号，因为编译器无法区分这里是函数声明还是实例化对象
//
//	d1.Print();
//	d2.Print();
//	// d3.Print();// error C2228: “.Print”的左边必须有类/结构/联合
//
//	return 0;
//}
//

//// 析构函数
//
//#include <iostream>
//using namespace std;
//typedef int STDataType;
//class Stack
//{
//public:
//	// 构造函数
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败！");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	// 若果不写栈的析构函数，就会出现内存泄漏！
//	~Stack()
//	{
//		cout << "~Stack()" << endl;// 表明调用了栈的析构
//		free(_a);// 释放掉有资源生成的_a
//		_a = nullptr;// 置空
//		_top = _capacity = 0;// 变值归零
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//
//class MyQueue
//{
//public:
//	~MyQueue()// 调试观察会不会调用这个自己实现的析构函数
//	{
//		cout << "~MyQueue()" << endl;
//	}
//private:
//	Stack pushst;
//	Stack popst;
//};
//
//int main()
//{
//	// Stack st;
//	MyQueue mq;// 调试结果哦：调用了两次栈的构造函数、两次栈的析构函数
//
//	return 0;
//}

// 拷贝构造函数——某种拷贝构造函数的第一个参数是自身类类型的引用，额外的参数必须有缺省值，这种构造函数就是拷贝构造函数
//
//#include <iostream>
//using namespace std;
//
//class Date
//{
//public:
//	// 全缺省构造函数
//	Date(int year = 1998, int month = 1, int day = 1)// 构造函数：函数名和类名相同，没有返回值
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//
//	//// 拷贝构造函数
//	//Date(const Date& d)// 第一个参数是类类型的引用
//	//	// 函数名相同，参数不同——重载函数
//	//{
//	//	_year = d._year;
//	//	_month = d._month;
//	//	_day = d._day;
//	//}// 如果不显示实现，编译器会自动生成一份拷贝构造函数——完成的是浅拷贝
//
//	void Print()
//	{
//		cout << _year << "年" << _month << "月" << _day << "日" << endl;
//	}
//
//	// 3. 在类里面实现operator==，但是第一个参数是隐含的this指针，所以看起来我们只写了一个参数
//	bool operator==(Date d2)
//	{
//		return _year == d2._year
//			&& _month == d2._month
//			&& _day == d2._day;
//	}
//
//	// 提供get函数
//	//int GetYear()
//	//{
//	//	return _year;
//	//}
//
//	//int Getmonth()
//	//{
//	//	return _month;
//	//}	
//	//
//	//int GetDay()
//	//{
//	//	return _day;
//	//}
//
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//
//int main()
//{
//	Date x1(2024, 1, 1);
//	Date x2(2024, 1, 1);
//	// operator==(x1, x2);  // 这种用不了？？？
//
//	int a = x1.operator==(x2);
//
//	x1 == x2;
//
//	return 0;
//}
//
//// 1. 注释掉private，将成员变量放成公有：这种方法ok，但是私有成员变量变成公有就容易被修改！
//bool operator==(const Date d1, const Date d2)
//{
//	return d1._year == d2._year
//		&& d1._month == d2._month
//		&& d1._day == d2._day;
//}

//// 2. 在类里面提供get函数
//bool operator==(const Date d1, const Date d2)
//{
//	return d1._year == d2._year
//		&& d1._month == d2._month
//		&& d1._day == d2._day;
//}


//#include<iostream>
//using namespace std;
//typedef int STDataType;
//
//class Stack
//{
//public:
//	Stack(int n = 4)// 构造函数
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//
//	// 拷贝构造函数
//	Stack(const Stack& st)// ?????
//	{
//		// 
//		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败！");
//			return;
//		}
//		memcpy(_a, st._a, sizeof(STDataType) * st._top);
//		_top = st._top;
//		_capacity = st._capacity;
//	}
//
//	void Push(STDataType x)
//	{
//		if (_top == _capacity)
//		{
//			int newcapacity = _capacity * 2;
//			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
//				sizeof(STDataType));
//			if (tmp == NULL)
//			{
//				perror("realloc fail");
//				return;
//			}
//			_a = tmp;
//			_capacity = newcapacity;
//		}
//		_a[_top++] = x;
//	}
//
//	~Stack()//析构
//	{
//		cout << "~Stack()" << endl;
//		free(_a);
//		_a = nullptr;
//		_top = _capacity = 0;
//	}
//private://内置类型
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//int main()
//{
//	Stack st1;
//	st1.Push(1);
//	st1.Push(2);
//
//	Stack st2(st1);
//	//Stack不显示实现拷贝构造函数，而是用自动生成的拷贝构造函数完成了浅拷贝
//	//调试发现，程序崩溃：因为st1和st2⾥⾯的_a指针指向同一块资源同一块空间，而且析构函数运行了两次，即同一块空间被析构了两次。
//
//	return 0;
//}

// 赋值运算符重载


#include <iostream>
using namespace std;

class Date
{
public:
	// 全缺省构造函数
	Date(int year = 1998, int month = 1, int day = 1)// 构造函数：函数名和类名相同，没有返回值
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

	bool operator==(Date d2)
	{
		return _year == d2._year
			&& _month == d2._month
			&& _day == d2._day;
	}

	// 建议传参：const类类型的引用——避免无穷递归
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;

		return *this;
	}


private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 1, 1);
	Date d2(1998, 1, 1);
	d1.Print();
	d2.Print();

	d1 = d2;// 两个已经存在的对象之间的拷贝赋值
	d1.Print();
	d2.Print();


	Date d3(d2);// 
	d3.Print();

	Date d4 = d2;
	d4.Print();

	return 0;
}

